﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;
using UnityEngine;

public class SocketClient
{
    Socket socket;
    private const int BufferSize = 1024 * 4;
    byte[] buffer = new byte[BufferSize];

    MemoryStream memStream;
    BinaryReader reader;

    public SocketClient(string ip, int port)
    {
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Connect(ip, port);
        Debug.Log("server connected:" + socket.RemoteEndPoint);

        //初始化内存流
        memStream = new MemoryStream();
        reader = new BinaryReader(memStream);

        StartReceive();
    }

    void StartReceive()
    {
        if (socket == null && socket.Connected == false)
        {
            Debug.LogError("连接失败，无法发送数据");
            return;
        }
        //开启异步读取
        socket.BeginReceive(buffer, 0, BufferSize, SocketFlags.None, OnReadCallback, null);

    }
    /// <summary>
    /// 断开连接
    /// </summary>
    public void Close()
    {
        Debug.Log("server close");
        socket.Close();
    }

    private void OnReadCallback(IAsyncResult ar)
    {
        try
        {
            int readCount = socket.EndReceive(ar);
            if (readCount < 1) throw new Exception();

            OnReceive(buffer, readCount);
            Array.Clear(buffer, 0, BufferSize);

            StartReceive();
        }
        catch (Exception e)
        {
            Debug.Log(e.ToString());
            Close();
        }
    }

    //粘包处理
    void OnReceive(byte[] bytes, int length)
    {
        //数据的追加
        memStream.Seek(0, SeekOrigin.End);
        memStream.Write(bytes, 0, length);
        memStream.Seek(0, SeekOrigin.Begin);

        int lengthCount = 4;
        while (RemainingBytes() > lengthCount)
        {
            int messageLength = reader.ReadInt32();
            if (RemainingBytes() >= messageLength)
            {
                byte[] result = reader.ReadBytes(messageLength);
                OnMessage(result);
            }
            else
            {
                memStream.Position = memStream.Position - lengthCount;
                break;
            }
        }

        //把剩余的字节保存起来，已经读取的字节全部丢弃
        byte[] leftBytes = reader.ReadBytes((int)RemainingBytes());
        memStream.SetLength(0);
        memStream.Write(leftBytes, 0, leftBytes.Length);
    }

    long RemainingBytes()
    {
        return memStream.Length - memStream.Position;
    }

    //接受到一条消息的流
    void OnMessage(byte[] result)
    {
        ByteBuffer buff = new ByteBuffer(result);

        //数据抛出到主线程
        NetworkManager.Instance.OnReceive(buff);
    }

    void OnWrite(byte[] bytes)
    {
        ByteBuffer buff = new ByteBuffer();
        buff.WriteInt(bytes.Length);
        buff.WriteBytes(bytes);

        byte[] result = buff.ToBytes();
        socket.Send(result);
        buff.Close();
    }

    public void Send(int cmd, byte[] content)
    {
        ByteBuffer buff = new ByteBuffer();
        buff.WriteInt(cmd);
        buff.WriteBytes(content);

        OnWrite(buff.ToBytes());
        buff.Close();
    }
}
